class Filter {
  constructor() {
    this.currentParam = {};
    this.whitelist = new Set(['create_time', 'region', 'credit', 'min_integral', 'max_integral', 'min_age', 'max_age',
      'service_tag', 'min_duration', 'max_duration']);
  }

  //判断参数是否都合法
  //param必须是纯对象
  _isWhitelist(param) {
    for (let key in param) {
      if (!this.whitelist.has('' + key)) return false;
    }
    return true;
  }

  //同化参数 即合并类似latest和create_time两个参数,这个过程称为同化,反之为逆同化
  _unitary(param) {
    if (param.latest) {
      param.create_time = param.latest;
      delete param.latest;
    }
    if (param.nearby) {
      param.region = param.nearby;
      delete param.nearby;
    }
    if (param.min_duration || param.max_duration) {
      param.max_duration && (param.duration = `:${param.max_duration}`);
      param.min_duration && (param.duration = `${param.min_duration}:`);
      param.min_duration && param.max_duration && (param.duration = `${param.min_duration}:${param.max_duration}`);
      delete param.min_duration;
      delete param.max_duration;
    }
    return param;
  }

  //逆同化
  _unUnitary(param) {
    if (param.create_time && param.create_time === true) {
      param.latest = true;
      delete param.create_time;
    }
    if (param.region && param.region === true) {
      param.nearby = true;
      delete param.region;
    }
    if (param.duration) {
      const duration = param.duration.split(':');
      duration[0] && (param.min_duration = duration[0]);
      duration[1] && (param.max_duration = duration[1]);
      delete param.duration;
    }
    return param;
  }

  update(param = {}) {
    //参数同化
    param = this._unitary(param);
    //检查白名单
    if (!this._isWhitelist(param)) {
      console.error('error in param of filter :', param);
    }
    //合并参数
    return Object.assign(this.currentParam, param);
  }

  delete(key) {
    return delete this.currentParam[key];
  }

  //获取用于显示的参数
  getCurrentParam() {
    return this.currentParam;
  }

  //获取于接口调用的参数
  getParamForHttp() {
    // 逆同化
    // !! 注意这里需要深拷贝,否则逆同化操作会修改currentParam.结果就是latest:true这个属性始终存在
    let newFilter = this._unUnitary(JSON.parse(JSON.stringify(this.currentParam)));
    // 转化tags对象为数组
    if (newFilter.service_tag) {
      let tags = [];
      Object.keys(newFilter.service_tag).forEach(tag => tags.push(tag));
      newFilter.service_tag = tags;
    }
    return newFilter;
  }

  reset() {
    this.currentParam = {};
  }
}
function setParam(dataset, inputValue, ...arg) {
  let param = {};
  let { key, type, value, scene } = dataset;
  if (scene === 'cancel') {
    console.info(`参数管理器 模式:删除参数; key:${key}`);
    if (key === 'nearby' || key === 'region') filter.delete('region');
    else if (key === 'latest' || key === 'create_time') filter.delete('create_time');
    else if (key === 'credit' || key === 'duration') filter.delete(key);
    else if (key === 'tag') {
      let tags = filter.currentParam.service_tag;//上一个状态的tags
      delete tags[value];
      if (Object.keys(tags).length !== 0) param['service_tag'] = tags;
      else filter.delete('service_tag');
    } else filter.delete(key);
  }
  else {
    console.info(`参数管理器 模式:添加参数; key:${key}`);
    if (key === 'nearby' || key === 'latest' || key === 'credit') param[key] = true;
    else if (key === 'integral') {
      if (inputValue) {
        type === 'min' && (param['min_integral'] = inputValue);
        type === 'max' && (param['max_integral'] = inputValue);
      } else {
        param['min_integral'] = dataset.min;
        param['max_integral'] = dataset.max;
      }
    }
    else if (key === 'age') {
      if (inputValue) {
        type === 'min' && (param['min_age'] = inputValue);
        type === 'max' && (param['max_age'] = inputValue);
      } else {
        param['min_age'] = dataset.min;
        param['max_age'] = dataset.max;
      }
    }
    else if (key === 'duration') {
      dataset.min && (param['min_duration'] = dataset.min);
      dataset.max && (param['max_duration'] = dataset.max);
    }
    else if (key === 'tag') {
      let tags = filter.currentParam.service_tag;//上一个状态的tags
      if (!tags) tags = {};
      tags[value] = true;
      param['service_tag'] = tags;
    }
    else {
      param[key] = value;
    }
  }
  return param;
}
let filter = new Filter();
export { filter, setParam};